package com.itheima.nio.tomcat.domain;

import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.List;

/**
 * 这个类的主要作用，封装Http请求协议中的数据
 */
public class HttpRequest {

    private String method ;             // 请求方式
    private String requestURI ;         // 请求的uri：客户端请求服务端的资源路径
    private String version ;            // http请求协议版本
    private List<Header> headers ;      // 请求头的集合

    // 构造方法的作用就是去接收SelectionKey，后期我们可以通过SelectionKey，获取通道信息，然后读取数据
    private SelectionKey selectionKey ;
    public HttpRequest(SelectionKey selectionKey) {
        this.selectionKey = selectionKey ;
    }

    public String getMethod() {
        return method;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public String getRequestURI() {
        return requestURI;
    }

    public void setRequestURI(String requestURI) {
        this.requestURI = requestURI;
    }

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    public List<Header> getHeaders() {
        return headers;
    }

    public void setHeaders(List<Header> headers) {
        this.headers = headers;
    }

    public SelectionKey getSelectionKey() {
        return selectionKey;
    }

    public void setSelectionKey(SelectionKey selectionKey) {
        this.selectionKey = selectionKey;
    }

    // 在提供一个parse方法，解析数据将数据封装到该对象的属性上
    public void parse() {


        try {

            // 就是读取Http请求协议中的数据，然后对数据进行解析，把解析到的数据封装到HttpRequest对象的相关属性上
            /**
             * 1. 创建一个StringBuilder对象，因为我们读取到的数据都是字符串
             */
            StringBuilder sb = new StringBuilder() ;

            // 2. 读取数据
            SocketChannel socketChannel = (SocketChannel) selectionKey.channel() ;
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            int read = socketChannel.read(byteBuffer);
            while(read > 0) {
                byteBuffer.flip();                              // 读写转换
                byte[] array = byteBuffer.array();              // 把byteBuffer转换成字节数组
                String s = new String(array , 0 , read) ; // 把字节数组转换成字符串
                sb.append(s) ;                                  // 把字符串添加到StringBuilder中
                byteBuffer.clear();                             // 把byteBuffer进行清空
                read = socketChannel.read(byteBuffer);          // 继续读取数据
            }

            // 解析Http请求协议中的数据
            praseHttpRequest(sb);

        }catch ( Exception e) {
            e.printStackTrace();
        }


    }

    // 解析Http请求协议中的数据
    private void praseHttpRequest(StringBuilder sb) {

        // 请求行 ， 请求头 ， 请求行和请求头之间存在换行 ， 每一个请求头占用一行
        String httpRequestStr = sb.toString();

        // 按照换行符进行切割
        String[] split = httpRequestStr.split("\r\n");

        // 获取请求行数据
        String httpRequestLine = split[0];   // 请求行数据的格式： GET / HTTP/1.1

        String[] httpRequestLineInfo = httpRequestLine.split(" ");
        this.method = httpRequestLineInfo[0] ;
        this.requestURI = httpRequestLineInfo[1] ;
        this.version = httpRequestLineInfo[2] ;

        // 解析请求头的数据
        ArrayList<Header> headers = new ArrayList<Header>() ;
        for(int x = 1 ; x < split.length ; x++) {

            // 请求头格式：头的名称: 值
            String requestHeaderInfo = split[x] ;
            String[] requestHeaderInfoArr = requestHeaderInfo.split(": ");

            // 创建一个Header对象
            Header header = new Header() ;
            header.setName(requestHeaderInfoArr[0]);
            header.setValue(requestHeaderInfoArr[1]);

            // 把这个请求头对象存储到一个集合
            headers.add(header) ;

        }

        // 把headers赋值给我们的HttpRequest类中的headers
        this.headers = headers ;


    }

}



















